<template>
  <view>
    <el-button round size="small" @click="isShowContainer = true" :type="btnType">
      <GdIcon icon-name="edit"></GdIcon>
      {{ btnText }}
    </el-button>
    <GdContainerWithBtns
      v-model:isShowContainer="isShowContainer"
      :container-attr="{ title: `编写代码(${lang})`, appendToBody: true }"
      @do-operation="onDoOperation"
    >
      <template #default>
        <view v-show="codeAdviceOptions.length > 0" class="cond-container">
          <text>模板代码：</text>
          <el-select v-model="pickedCodeAdviceVal" @change="onChangeCodeAdviceVal">
            <el-option
              v-for="item in codeAdviceOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </view>
        <gd-codemirror v-if="isShowContainer" :lang="lang" :code="code" ref="gdCodemirrorRef"></gd-codemirror>
      </template>
    </GdContainerWithBtns>
  </view>
</template>
<script>
  export default {
    inheritAttrs: false,
  };
</script>
<script setup>
  import { ref, toRefs, useAttrs, computed, watch, onMounted } from "vue";
  import GdIcon from "@gd-accbuild-ui/gd-ui/gd-icon/gd-icon.vue";
  import GdContainerWithBtns from "@gd-accbuild-ui/gd-ui/gd-container-with-btns/gd-container-with-btns.vue";

  const props = defineProps({
    modelValue: {
      type: [String, Object],
    },
    btnText: {
      type: String,
    },
    btnType: {
      type: String,
    },
    pickedDefaultCodeAdviceVal: {
      type: String,
    },
    codeAdviceOptions: {
      type: Array,
      default: () => [],
    },
    lang: {
      type: String,
      default: "javascript",
    },
    textWrapperConfig: {
      type: Object,
      default: () => ({}),
    },
  });
  const emits = defineEmits(["update:modelValue", "change"]);
  const bindValue = computed({
    get() {
      return props.modelValue;
    },
    set(value) {
      emits("change", value);
      emits("update:modelValue", value);
    },
  });

  const isShowContainer = ref(false);
  const btnText = computed(() => {
    return props?.btnText ?? `编写${props.lang}`;
  });

  /////////////////

  const pickedCodeAdviceVal = ref("");
  const onChangeCodeAdviceVal = (val) => {
    const matchedItem = props.codeAdviceOptions.find((el) => el.value === val);
    bindValue.value = matchedItem.data;
  };
  watch(
    () => props.pickedDefaultCodeAdviceVal,
    (newVal, oldVal) => {
      if (newVal && !bindValue.value) {
        pickedCodeAdviceVal.value = newVal;
        onChangeCodeAdviceVal(newVal);
      }
    },
    { immediate: true }
  );
  ///////////////////////

  const code = computed(() => {
    let retCode = "";
    if (typeof bindValue.value === "string") {
      retCode = bindValue.value;
    } else if (typeof bindValue.value === "object") {
      retCode = JSON.stringify(bindValue.value, null, "\t");
    } else {
      retCode = "";
    }
    if (props.lang === "javascript") {
      retCode = `${prefixTextWrapper.value}\n${retCode}\n${suffixTextWrapper.value}`;
    }
    return retCode;
  });
  const isRemoveTextWrapperWhenSubmit = computed(() => {
    return props.textWrapperConfig?.isRemoveWhenSubmit ?? true;
  });
  const hasTextWrapper = computed(() => {
    return Object.keys(props.textWrapperConfig).length > 0;
  });
  const prefixTextWrapper = computed(() => {
    if (hasTextWrapper.value) {
      return props.textWrapperConfig?.prefixText ?? "";
    } else {
      return "";
    }
  });
  const suffixTextWrapper = computed(() => {
    if (hasTextWrapper.value) {
      return props.textWrapperConfig?.suffixText ?? "";
    } else {
      return "";
    }
  });

  const gdCodemirrorRef = ref(null);
  const onDoOperation = (params) => {
    if (params.metaKey === "buildInContainerSubmitBtn") {
      if (props.lang === "json") {
        bindValue.value = JSON.parse(gdCodemirrorRef.value.localCode);
      } else if (props.lang === "javascript") {
        let str = gdCodemirrorRef.value.localCode.trim();
        if (isRemoveTextWrapperWhenSubmit.value) {
          str = str.replace(prefixTextWrapper.value.trim(), "");
          const lastIndex = str.lastIndexOf(suffixTextWrapper.value);
          str = `${str.substring(0, lastIndex)}${str.substring(lastIndex + 1)}`.trim();
        }
        bindValue.value = str;
      }
      isShowContainer.value = false;
    }
  };

  ////////////////
  /* const onKeyDown = (e) => {
    if (e.ctrlKey && e.altKey) {
      onDoOperation({ metaKey: "buildInContainerSubmitBtn" });
      e.preventDefault();
    }
  };
  watch(isShowContainer, (newVal, oldVal) => {
    if (newVal) {
      document.body.addEventListener("keydown", onKeyDown, false);
    } else {
      document.body.removeEventListener("keydown", onKeyDown, false);
    }
  }); */
</script>
<style lang="scss" scoped>
  .cond-container {
    margin-bottom: 10px;
    height: 40px;
    position: sticky;
    top: 0;
    z-index: 1000;
    width: 100%;
    background-color: #fff;
  }
</style>
